package operate;

import handle.LocalGetFileUpHandle;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JOptionPane;

import model.command.CommandLogout;
import model.command.ConnectComand;
import model.command.SendFileCommand;
import model.command.SendFileListCommand;
import utils.CloseUtil;
import viewer.ClientFrame;

import common.Client;
import common.ClientOperate;
import common.Command;

public class LocalClientOperate extends ClientOperate {
	
	/** 文件更新通知port */
	private Integer waitNotifyport = Integer.parseInt(Client.rb.getString("port"));
	/** 文件更新通知到达的界面 */
	ClientFrame frame;
	
	public LocalClientOperate(Client client, ClientFrame frame) {
		this.client = client;
		this.frame = frame;
	}
	@Override
	public void connect() {
		connect(client.getAddress(), client.getPort());
	}
	@Override
	public void getFile(String fileName, boolean off) {
		getFile(client.getAddress(), client.getPort(), fileName, off);
	}
	@Override
	public void getListShareFile() {
		getListShareFile(client.getAddress(), client.getPort());
	}
	@Override
	public void sendLogout() {
		sendLogout(client.getAddress(), client.getPort());
	}

	private void getListShareFile(final String address, final Integer port) {
		
		try {
			Socket socket = new Socket(address, port);
			if (!client.started) {
				client.started = true;
				SendFileListCommand sendCommand = (SendFileListCommand) sendCmd(new SendFileListCommand(), socket);
				client.setListShareFile( sendCommand.getListShareFile() );
				CloseUtil.closeSocket(socket);
				client.started = false;
			}
		} catch (UnknownHostException e) {
			System.out.println("ERROR: can't connect server :[ ip: " + client.getAddress() + ", port: " + client.getPort() + "]");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("ERROR: can't connect server :[ ip: " + client.getAddress() + ", port: " + client.getPort() + "]");
			e.printStackTrace();
		}
	}
	private void connect (final String address, final Integer port) {

		try {
			Socket socket = new Socket(address, port);
			if (!client.started) {
				client.started = true;
				Command command = new ConnectComand(waitNotifyport);
				Command recmd = (Command)sendCmd(command, socket);
				if( recmd.getCommand().equals(Command.IP_LIMIT) ){// check ip limit message
					JOptionPane.showMessageDialog(frame, "IP 受到限制,请联系管理员");
				}else {
					SendFileListCommand sendCommand = (SendFileListCommand) recmd;
					client.setListShareFile( sendCommand.getListShareFile() );
				}
				client.started = false;
			}
			CloseUtil.closeSocket(socket);
		} catch (UnknownHostException e) {
			System.out.println("ERROR: can't connect server :[ ip: " + client.getAddress() + ", port: " + client.getPort() + "]");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("ERROR: can't connect server :[ ip: " + client.getAddress() + ", port: " + client.getPort() + "]");
			e.printStackTrace();
		}
	}
	
	private void getFile (final String address, final Integer port, String fileName, boolean off) {
		
		try {
			Socket socket = new Socket(address, port);
			if (!client.started) {
				client.started = true;
				SendFileCommand command = new SendFileCommand(fileName);
				command.setPort(waitNotifyport);// 文件更新监听端口
				if (off) { // set 跳过多少字符读取,off:true (continue read curr file)
					command.setFileSeek(client.getFileSeek());
				} else {
					command.setFileSeek(0L);
				}
				sendCmdGetFile(command, socket, off);
//				client.setFile(file.getFile());
//				client.setEncoding(file.getEncoding());
				client.setFileName(fileName);
				if (!client.waitNotifyStarted) {// 等待文件更新通知
					LocalGetFileUpHandle waitNotifyThread = new LocalGetFileUpHandle(waitNotifyport, this);
					waitNotifyThread.start();
					client.waitNotifyStarted = true;
				}
				CloseUtil.closeSocket(socket);
				client.started = false;
			}
		} catch (UnknownHostException e) {
			System.out.println("ERROR: can't connect server :[ ip: " + client.getAddress() + ", port: " + client.getPort() + "]");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("ERROR: can't connect server :[ ip: " + client.getAddress() + ", port: " + client.getPort() + "]");
			e.printStackTrace();
		}
	}
	private void sendLogout(final String address, final Integer port) {

		try {
			Socket socket = new Socket(address, port);
			if (!client.started) {
				client.started = true;
				CommandLogout command = new CommandLogout(waitNotifyport);
				ObjectOutputStream cmdOut = new ObjectOutputStream(socket.getOutputStream());
				cmdOut.writeObject(command);
				cmdOut.flush();
				client.started = false;
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	protected synchronized void sendCmdGetFile(Command cmd, Socket socket, boolean off) {
		
		try {
			ObjectOutputStream cmdOut = new ObjectOutputStream(socket.getOutputStream());
			cmdOut.writeObject(cmd);
			cmdOut.flush();
			InputStream inputStream = socket.getInputStream();
			Long total = 0L;
			int i = inputStream.available();
			byte []bs = new byte[i+1];
			while (inputStream.read(bs) > 0) {
				total += i;
				System.out.println("read length : " + i);
				if (bs.length != 0) {
					frame.readFileArea.append(new String(bs));
				}
				i = inputStream.available();
				bs = new byte[i+1];
			}
			System.out.println("CLOSE");
			if (off) {// 文件读到的位置
				client.setFileSeek(client.getFileSeek() + total);
			} else {
				client.setFileSeek(total);
			}
			inputStream.close();
		} catch (IOException e) {
			System.out.println("ERROR: can't connect server :[ ip: " + client.getAddress() + ", port: " + client.getPort() + "]");
			System.out.println("Send command ERROR!");
			e.printStackTrace();
		}
	}
}
